package com.teragadgets.android.gameboy;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;

public class RomView extends Activity implements OnTouchListener {

	static RomView instance;
	private boolean hidetop;
	private GLSurfaceView surface;
	private int romId;
	private String romName, romPath;
	private boolean touch, drawFPS;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		instance = this;

		romId = this.getIntent().getIntExtra("romId", -1);
		romName = this.getIntent().getStringExtra("romName");
		romPath = this.getIntent().getStringExtra("romPath");

		hidetop = KiddGBC.prefs.getBoolean("hidetop", false);
		if (hidetop) {
			requestWindowFeature(Window.FEATURE_NO_TITLE);
			getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
					WindowManager.LayoutParams.FLAG_FULLSCREEN);
		}

		drawFPS = KiddGBC.prefs.getBoolean("drawFPS", true);

		surface = new GLSurfaceView(this);
		surface.setRenderer(new RomRenderer());
		this.setContentView(surface);
		touch = KiddGBC.prefs.getBoolean("touch", false);
		if (touch) {
			addTouchControls();
		}
	}

	private void addTouchControls() {
		LinearLayout touchButtons = new LinearLayout(this);
		touchButtons.setOrientation(LinearLayout.VERTICAL);

		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
		params.weight = 1;

		Button aButton = new Button(this);
		aButton.setFocusable(false);
		aButton.setMinWidth(50);
		aButton.setLayoutParams(params);
		aButton.setText("A");
		aButton.setOnTouchListener(this);
		touchButtons.addView(aButton);

		Button bButton = new Button(this);
		bButton.setFocusable(false);
		bButton.setMinWidth(50);
		bButton.setLayoutParams(params);
		bButton.setText("B");
		bButton.setOnTouchListener(this);
		touchButtons.addView(bButton);

		this.addContentView(touchButtons, new LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));
	}

	@Override
	protected void onStart() {
		super.onStart();
		surface.runRom();
	}

	private int[] previousTime = new int[16];
	private int previousTimeIx;
	private int estfps;

	public void drawFPS() {
		if (hidetop || !drawFPS)
			return;
		int now = (int) System.currentTimeMillis();
		// calculate moving-average fps
		// 17 ms * 60 fps * 2*16 seconds = 32640 ms
		estfps = ((32640 + now - previousTime[previousTimeIx]) / (now - previousTime[previousTimeIx])) >> 1;
		previousTime[previousTimeIx] = now;
		previousTimeIx = (previousTimeIx + 1) & 0x0F;

		runOnUiThread(thread);
	}

	private final Thread thread = new Thread() {
		public void run() {
			setTitle("Kidd GBC --- " + romName + " (" + estfps + "fps)");
		};
	};

	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (touch && keyCode == KeyEvent.KEYCODE_BACK) {
			RomController.keyDown(touch, RomController.key[7]);
			return true;
		} else if (touch && keyCode == KeyEvent.KEYCODE_CALL) {
			RomController.keyDown(touch, RomController.key[6]);
			return true;
		}
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			GLSurfaceView.mGLThread.requestExitAndWait();
			finish();
		}
		super.onKeyDown(keyCode, event);
		RomController.keyDown(touch, keyCode);
		return false;
	}

	public boolean onKeyUp(int keyCode, KeyEvent event) {
		if (touch && keyCode == KeyEvent.KEYCODE_BACK) {
			RomController.keyUp(RomController.key[7]);
			return true;
		} else if (touch && keyCode == KeyEvent.KEYCODE_CALL) {
			RomController.keyUp(RomController.key[6]);
			return true;
		}
		super.onKeyUp(keyCode, event);
		RomController.keyUp(keyCode);
		return false;
	}

	@Override
	protected void onResume() {
		super.onResume();

		Dmgcpu.running = true;
		surface.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();

		System.out.println("Paused");
		Dmgcpu.running = false;
		surface.onPause();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		GLSurfaceView.mGLThread.requestExitAndWait();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, 1, 0, "Save");
		menu.add(0, 2, 0, "Load");
		menu.add(0, 3, 0, "End Game");
		System.out.println("Created options menu");
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		Dmgcpu.running = false;
		surface.onPause();
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public void onOptionsMenuClosed(Menu menu) {
		Dmgcpu.running = true;
		surface.onResume();
		super.onOptionsMenuClosed(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case 1:
			Intent i = new Intent(RomView.this, SaveStates.class);
			i.putExtra("type", "save");
			i.putExtra("romId", romId);
			i.putExtra("romName", romName);
			i.putExtra("romPath", romPath);
			System.out.println("Save State Activity");
			startActivityForResult(i, 1);
			return true;
		case 2:
			Intent j = new Intent(RomView.this, SaveStates.class);
			j.putExtra("type", "load");
			j.putExtra("romId", romId);
			j.putExtra("romName", romName);
			j.putExtra("romPath", romPath);
			startActivityForResult(j, 2);
			return true;
		case 3:
			GLSurfaceView.mGLThread.requestExitAndWait();
			finish();
		}
		return false;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != Activity.RESULT_OK)
			return;
		if (data.getStringExtra("save").equals("load")) {
			GLSurfaceView.mGLThread.requestExitAndWait();
			romId = data.getIntExtra("romId", -1);
			romName = data.getStringExtra("romName");
			romPath = data.getStringExtra("romPath");
			RomController.loadRom(data.getStringExtra("state"));

			surface = new GLSurfaceView(this);
			surface.setRenderer(new RomRenderer());
			this.setContentView(surface);
			if (touch) {
				addTouchControls();
			}
			surface.runRom();
		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent motionEvent) {
		if (((Button) v).getText().equals("A")) {
			if (motionEvent.getAction() == MotionEvent.ACTION_DOWN)
				RomController.keyDown(touch, RomController.key[4]);
			else if (motionEvent.getAction() == MotionEvent.ACTION_UP)
				RomController.keyUp(RomController.key[4]);

		} else if (((Button) v).getText().equals("B")) {
			if (motionEvent.getAction() == MotionEvent.ACTION_DOWN)
				RomController.keyDown(touch, RomController.key[5]);
			else if (motionEvent.getAction() == MotionEvent.ACTION_UP)
				RomController.keyUp(RomController.key[5]);

		}
		return false;
	}
}
